<template>
  <div class="import-infomation-list">
    <div class="search-list">
      <p
        class="list-result-info"
        v-if="!isStatic">
        <slot
          name="listInfos"
          :resultInfo="resultInfo" />
      </p>
      <div class="delete-all-options-corver">
        <el-button
          type="text"
          class="del-btn"
          v-if="selection"
          @click.stop="deleteAllSel">删除所选</el-button>
      </div>
      <el-editable
        class="info-list"
        v-loading="tableLoading"
        height="200px"
        style="height:100%;"
        :editable-method="editableMethod"
        ref="editable"
        :data="productControlList"
        :columns="resetColumns"
        @selection-change="handleSelectionChange"
      >
        <template
          slot-scope="scope"
          slot="default-order">{{ scope.$index + 1 }}</template>
        <template
          slot-scope="scope"
          slot="default-errors"
        >
          <el-button
            v-if="showJournalBtn"
            type="text"
            @click="journalDetailShow(scope)">日志详情</el-button>
        </template>
        <template
          slot-scope="scope"
          slot="default-options">
          <el-button
            v-if="showEditBtn"
            type="text primary"
            @click="editItem(scope)">修改</el-button>
          <el-button
            type="text text-danger"
            @click="deleteItem(scope)">删除</el-button>
        </template>
      </el-editable>
    </div>
    <el-pagination
      align="right"
      class="pagination"
      v-if="needPagination"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="page.curPage"
      :page-sizes="PAGE_NUMBER"
      :page-size="page.pageSize"
      :layout="PAGINATION_LAYOUT"
      :total="page.total"
    />
    <!-- 日志详情 -->
    <el-dialog
      title="错误日志"
      :visible.sync="dialogVisible"
      width="30%"
      :before-close="handleClose">
      <div>
        <div
          v-for="(item,index) in journalDetails"
          :key="index"
          style="margin-bottom:10px;">
          <span>{{ item }}</span>
        </div>
        <!-- <div style="margin-bottom:10px;">
          <span>{{ this.journalDetails }}</span>
        </div> -->
      </div>
    </el-dialog>
  </div>
</template>
<script>
import { PAGE_NUMBER, PAGINATION_LAYOUT } from '@const/common.js'
import ElEditable from '@components/el-editable/index.vue'
import { cloneDeep, hasIn } from 'lodash'
import { setTimeout } from 'timers'
import { mappingDeleteThirdItem } from '@const/api.js'

export default {
  name: 'ImportInfomationList',
  components: {
    ElEditable
  },
  data () {
    return {
      tableLoading: false,
      resetColumns: [],
      productControlList: [],
      PAGE_NUMBER, // 分页类型
      PAGINATION_LAYOUT, // 分页功能
      page: {
        pageSize: PAGE_NUMBER[0],
        curPage: 1,
        total: 0
      },
      resultInfo: {
        total: 0,
        needEdit: 0
      },
      // 所有选中的数据
      allSelData: [],
      // 缓存axios传入的配置参数
      prductsCntroListStorgData: {},
      dialogVisible: false,
      // journalDetail: [
      //   { title: '标题', content: '内容' },
      //   { title: ' 标题', content: '内容' }
      // ],
      journalDetails: []
    }
  },
  props: {
    submitLoading: {
      type: Boolean,
      default: false
    },
    columns: {
      type: Array,
      default: () => []
    },
    // 是否显示编辑按钮
    showEditBtn: {
      type: Boolean,
      default: false
    },
    // 是否显示日志详情按钮
    showJournalBtn: {
      type: Boolean,
      default: false
    },
    // 是否有多选框
    selection: {
      type: Boolean,
      default: false
    },
    // 表格内容是否可以修改
    isStatic: {
      type: Boolean,
      default: true
    },
    // 从父组件传过来的删除api
    deleteApi: {
      type: String,
      default: ''
    },
    // 从父组件传过来的详情api
    erroApi: {
      type: String,
      default: ''
    },
    // 从父组件传过来的统计api
    analysisApi: {
      type: String,
      default: ''
    },
    // 从父组件传过来的提交修改api
    correctWrongData: {
      type: String,
      default: ''
    },
    // 父组件传入的唯一标识的key quantity
    idStr: {
      type: String,
      default: 'id'
    },
    // 父组件传入新增的单位转换系数key quantity
    // quantity: {
    //   type: String,
    //   default: 'unitcompany'
    // },
    // 是否需要分页组件，默认是需要
    needPagination: {
      type: Boolean,
      default: true
    }
  },
  methods: {
    // 数据修改部分
    // 修改当前列内容
    // 只读页面也就是readThirdPartyInfo父页面的方法，跳转到对应的更新详情页
    editItem (scope) {
      this.$router.push(
        `/productManagement/compareManagement/updateThirdPartyInfo?id=${
          scope.row.id.value
        }`
      )
    },
    handleSelectionChange (val) {
      this.allSelData = val
    },
    journalDetailShow (scope) {
      // console.log(scope);
      this.journalDetails = scope.row.errorInfo.value.split(',')
      this.dialogVisible = true
    },
    handleClose () {
      this.dialogVisible = false
    },
    // 删除所有选中
    deleteAllSel () {
      this.$confirm('确定选中的全部内容删除？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        if (this.allSelData.length > 0) {
          this.selWayToDelete(this.allSelData)
        } else {
          this.$message({ type: 'warning', message: '您还未选中要删除的内容' })
        }
      })
    },
    // 删除当前列内容
    deleteItem (scope) {
      this.$confirm('确定删除？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        let arr = []
        arr.push(scope.row)
        this.selWayToDelete(arr)
      })
    },
    // 删除的时候，根据isStatic的状态不同，来进行不同的逻辑及接口
    selWayToDelete (arrData) {
      // 根据两种状态来决定采用哪种方式
      if (this.isStatic) {
        let arr = []
        let obj = {}
        arrData.forEach(item => {
          arr.push(item.id.value)
        })
        obj = {
          cid: arrData[0].enterpriseId.value,
          itemIds: arr
        }
        this._deleteSel(obj)
      } else {
        let arr = []
        arrData.forEach(item => {
          arr.push(item[this.idStr].value)
        })
        this._deleteSel(arr)
      }
    },
    // 整合后，以供删除统一调用的接口，无论是单个还是多选，都传入一个数组，这里是真正调用接口的部分
    _deleteSel (deleteArr) {
      let method = 'put'
      if (!this.isStatic) {
        method = 'delete'
      }
      this.tableLoading = true
      this.$axios({
        method: method,
        url: this.deleteApi,
        data: deleteArr
      })
        .then(res => {
          if (res.data.code === '0') {
            // 在每次更改后，父组件要监听状态
            this.$emit('uploadResult')
            this.$message({ type: 'success', message: '删除成功！' })
            this.tableLoading = false
          }
        })
        .catch(() => {
          this.tableLoading = false
        })
    },
    // 整合提交部分，提交最后的结果。
    // 获取本地存储中的数据，要注意，本地存储中的数据并不是最终要提交的结果
    _submitResut () {
      this._setChangeItemsStorage()
      var storageData = JSON.parse(window.localStorage.getItem('storageData')) || []
      // console.log(storageData, 'storageData')
      if (storageData.length > 0) {
        // 最终结果
        this.upLoadUniqueResult(this._getFullUniqueData(storageData))
      } else {
        this.$message({ type: 'warning', message: '您没有需要提交的修改数据' })
      }
    },
    upLoadUniqueResult (unique) {
      this.$axios({
        method: 'post',
        url: this.correctWrongData,
        data: unique
      }).then(res => {
        // el-editable清除之前存储的数据的方法
        this.$refs.editable.clearStore()
        this.$emit('uploadResult')
      })
    },
    // 数据整合部分
    handleSizeChange (pageSize) {
      this.page.pageSize = pageSize
      this._setChangeItemsStorage()
      this._getPrductsCntroList(this.prductsCntroListStorgData)
    },
    handleCurrentChange (curPage) {
      this.page.curPage = curPage
      this._setChangeItemsStorage()
      this._getPrductsCntroList(this.prductsCntroListStorgData)
    },
    // 改变当前页时，获取本地存储的修改信息，匹配当前页数据后反显
    _resetChangedData () {
      let arr = JSON.parse(window.localStorage.getItem('storageData')) || []
      if (arr.length === 0) return
      let uniqueArr = this._getFullUniqueData(arr)
      uniqueArr.forEach((item, index) => {
        this.productControlList.forEach((it, idx) => {
          if (item[this.idStr] === it[this.idStr].value) {
            for (var k in item) {
              it[k].value = item[k]
            }
          }
        })
      })
    },
    // 改变当前页的时候把更改的信息存储在本地，以待统一提交
    _setChangeItemsStorage () {
      // 如果是静态的则不需要执行此函数
      if (this.isStatic) return
      // el-editable获取列表修改的数据
      let changedValue = this.$refs.editable.getValue()
      // console.log(changedValue, 'changedValue')
      let arr = JSON.parse(window.localStorage.getItem('storageData')) || []
      // 先把所有更改的数据都拿出来放进一个数组
      changedValue.forEach(item => {
        let obj = {}
        obj[item.prop.split('.')[0]] = item.value
        obj[this.idStr] = item.row[this.idStr].value
        // obj[this.quantity] = item.row[this.quantity].value
        // console.log(obj);
        arr.push(obj)
      })
      // console.log(arr, 'arr')
      window.localStorage.setItem('storageData', JSON.stringify(arr))
    },
    // 去重方法,入参一个数组，出参一个数组orz...
    _getUnique (arr) {
      let uniqueArr = []
      let isRepeat
      for (var i = 0; i < arr.length; i++) {
        // 第一次循环
        isRepeat = false
        for (var j = i + 1; j < arr.length; j++) {
          // 第二次循环
          if (arr[i][this.idStr] === arr[j][this.idStr]) {
            isRepeat = true
            break
          }
        }
        if (!isRepeat) {
          uniqueArr.push(arr[i])
        }
      }
      return uniqueArr
    },
    // 单独把去重后赋值的方法独立出来，以用在不同的地方，返回一个全量的数组
    _getFullUniqueData (arr) {
      var storageData = JSON.parse(window.localStorage.getItem('storageData')) || []
      // 去重，拿到一个干净的，只有唯一不重复id的数组。无论数组内的数据是什么样的，只要id唯一且不重复即可
      var unique = cloneDeep(this._getUnique(arr))
      // 去重之后呢，往唯一id的数组里面加数据就完事啦omg
      unique.forEach(item => {
        storageData.forEach(itm => {
          if (item[this.idStr] === itm[this.idStr]) {
            item = Object.assign(item, itm)
          }
        })
      })
      return unique
    },
    // 根据列表的配置，传入可供修改的列表项
    editableMethod ({ row, column, rowIndex, columnIndex }) {
      if (this.isStatic) {
        return false
      } else {
        if (row[column.property.split('.')[0]]) {
          let isItemNeedEdit = row[column.property.split('.')[0]].isEdit
          if (isItemNeedEdit === 'false') return column.property
        } else {
          return false
        }
      }
    },
    // 获取主列表，也就是要修改的列表，父组件调用，根据传入的参数来请求接口
    _getPrductsCntroList (ajaxOps = { params: {}, data: {}, method: 'get' }) {
      this.prductsCntroListStorgData = ajaxOps
      if (ajaxOps.method === 'get') {
        ajaxOps.params = Object.assign({}, ajaxOps.params, {
          page: this.page.curPage,
          size: this.page.pageSize
        })
      } else {
        ajaxOps.data = Object.assign({}, ajaxOps.data, {
          page: this.page.curPage,
          size: this.page.pageSize
        })
      }
      this.tableLoading = true
      // this.submitLoading = true
      this.$axios(ajaxOps)
        .then(res => {
          let obj = hasIn(res, 'data.payload') ? res.data.payload : []
          // 临时前端假数据
          this.productControlList = obj.content
          // 更改获取的列表数组结构，以可用于前端页面
          this._resetDataStructure(this.productControlList)
          this.page.total = obj.totalElements
          // 数据是否准备完毕
          // let isReady = true
          // this.$emit('getPrdutsCtrLen', this.productControlList.length, isReady)
          this.$emit('getPrdutsCtrLen', this.productControlList.length)
          // 取消列表的loading
          this.tableLoading = false
          this.submitLoading = false
          // 获取数据成功后，重新返显内容
          this._resetChangedData()
        })
        .catch(() => {
          this.submitLoading = false
          this.tableLoading = false
        })
      if (!this.isStatic) {
        this.getAnalysis()
      }
    },
    // 获取列表的修改统计信息
    getAnalysis () {
      this.$axios({
        method: 'post',
        url: this.analysisApi,
        data: this.prductsCntroListStorgData.data
      }).then(res => {
        let payload = hasIn(res, 'data.payload') ? res.data.payload : {}
        // 设置结果信息
        this.resultInfo.total = payload.countSum
        this.resultInfo.needEdit = payload.errorSum
      })
    },
    // 重置获取的列表数据，以供前端使用
    _resetDataStructure (list) {
      list.forEach((item, index) => {
        let keys = Object.keys(item)
        keys.forEach((k, i) => {
          item[k] = {
            value: item[k] ? item[k].toString().split('%-%')[0] : '',
            isEdit: item[k] ? item[k].toString().split('%-%')[1] : ''
          }
        })
      })
      this.productControlList = cloneDeep(list)
    },
    // 组件功能配置部分
    // 根据传入的selection字段，动态添加checkbox
    _initListSelection () {
      if (this.selection) {
        let columns = cloneDeep(this.columns)
        columns.splice(0, 0, { width: '55', type: 'selection' })
        this.resetColumns = columns
      } else {
        this.resetColumns = this.columns
      }
    }
  },
  mounted () {
    this._initListSelection()
    // console.log(this.idStr,this.quantity)
  },
  created () {},
  destroyed () {
    // 离开页面，销毁保存在本地的修改数据
    window.localStorage.removeItem('storageData')
  }
}
</script>
<style lang="less">
.import-infomation-list {
  width: 100%;
  flex: 1;
  display: flex;
  flex-direction: column;

  .delete-all-options-corver {
    display: flex;
    flex-direction: row;
    justify-content: flex-end;

    .del-btn {
      color: #d85365;
    }
  }

  .search-list {
    height: calc(100% - 32px);
    flex: 1;
    display: flex;
    flex-direction: column;

    .info-list {
      flex: 1;
      overflow: auto;
    }

    .list-result-info {
      margin: 20px 0;
    }
  }

  .pagination {
    margin-top: 10px;
  }

  .info-list {
    flex: 1;

    .el-table__body-wrapper {
      .el-table__body {
        tbody {
          .el-table__row {
            .cell {
              .el-input {
                input {
                  border: 1px solid red;
                  white-space: nowrap;
                  text-overflow: ellipsis;
                  overflow: hidden;
                }
              }
            }
          }
        }
      }
    }
  }
}
</style>
